#include <ace/INET_Addr.h>
#include <ace/SOCK_Acceptor.h>
#include "GTATradeProvider.h"
#include "GTAListener.h"
#include "GTAReciever.h"
#include "RootKeyCreator.h"
#include "GTARecieverMgr.h"
#include "LogHelper.h"


namespace gta
{
	CGTAListener::CGTAListener(CGTATradeProvider*  provider):m_port(0)
	{
		m_provider = provider;
	}

	CGTAListener::~CGTAListener()
	{
		WriteLog("stdout",LTALL,"CGTAListener::~CGTAListener");
		Stop();
	}

	bool CGTAListener::Start( int port )
	{
		LogCallStack(CGTAListener_Start);
		WriteLog("stdout",LTALL,"GTAServer star listen port %d",port);

		m_port = port;

		ACE_INET_Addr port_to_listen(m_port);
		m_acceptor = std::shared_ptr<ACE_SOCK_Acceptor>(new ACE_SOCK_Acceptor);	

		WriteLog("stdout",LTALL,"start open port:%d to listen ",m_port);
		WriteLog("log",LTALL,"start open port:%d to listen ",m_port);


		int ret = m_acceptor->open(port_to_listen);
		if(ret)
		{
			WriteLog("stdout",LTALL,"open socket listener failed port:%d",port);
			WriteLog("error",LTALL,"open socket listener failed port:%d",port);
			return false;
		}

		WriteLog("log",LTALL,"start open port:%d to listen successed",m_port);

		if( this->activate() != 0)
		{
			WriteLog("stdout",LTALL,"create listen thread failed");
			WriteLog("error",LTALL,"create listen thread failed");
			return false;
		}

		WriteLog("log",LTALL,"start open port:%d to listen successed",m_port);

		return true;
	}

	void CGTAListener::Stop()
	{
		this->close(0);
		m_acceptor->close();		
	}

	int CGTAListener::svc()
	{
		WriteLog("stdout",LTALL,"start GTA listen thread");
		try
		{
			while (true)
			{
				//std::shared_ptr<ACE_SOCK_Stream> peer = std::shared_ptr<ACE_SOCK_Stream>(new ACE_SOCK_Stream);
				ACE_SOCK_Stream* peer = new ACE_SOCK_Stream;
				int ret = m_acceptor->accept (*peer);
				if (ret == -1)
				{
					WriteLog("stdout",LTALL, "receive a socket failed");
					WriteLog("error",LTALL,"receive a socket failed");
					return -1;
				}

				WriteLog("log",LTALL,"get a connection");
				WriteLog("stdout",LTALL,"get a connection");

				std::shared_ptr<CGTAReciever> preciever = std::shared_ptr<CGTAReciever>(new CGTAReciever(CRootKeyCreator::Create()	,std::shared_ptr<ACE_SOCK_Stream>(peer),this->m_provider));
				m_provider->GetCGTARecieverMgr()->AddReviever(preciever);
				preciever->Start();
			}

		}
		catch (...)
		{WriteLog("log",LTALL,"listen server get exception ");
		WriteLog("stdout",LTALL,"listen server get exception ");

		}

		return 0;
	}
}